package aftersale

import (
	"context"

	"mall/common/utils/pointy"
	userx "mall/common/utils/user"
	"mall/service/backend/api/internal/logic/order/util"
	"mall/service/backend/api/internal/logic/utils"
	"mall/service/backend/api/internal/logic/utils/parse"
	"mall/service/backend/api/internal/svc"
	"mall/service/backend/api/internal/types"
	"mall/service/backend/common/i18n"
	"mall/service/order/rpc/orderclient"

	"github.com/zeromicro/go-zero/core/logx"
)

type GetAfterSaleListLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

// 查询售后列表
func NewGetAfterSaleListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetAfterSaleListLogic {
	return &GetAfterSaleListLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *GetAfterSaleListLogic) GetAfterSaleList(req *types.BackendAfterSaleListReq) (*types.BackendAfterSaleListResp, error) {
	page, pageSize := parse.ParsePageInfo(
		req.Current,
		req.PageSize,
		l.svcCtx.Config.Query.DefaultAmount,
		l.svcCtx.Config.Query.MaxAmount,
	)

	orderBys := util.ParseSorter(req.Sorter)
	filterBys := util.ParseFilter(req.Filter, req.Type)
	data, err := l.svcCtx.OrderRpc.BackendGetAfterSaleList(l.ctx, &orderclient.BackendAfterSaleListReq{
		Page:          page,
		PageSize:      pageSize,
		Ids:           req.Ids,
		AfterSaleSn:   req.AfterSaleSn,
		OrderSn:       req.OrderSn,
		ProductId:     req.ProductId,
		UserId:        req.UserId,
		Mobile:        req.Mobile,
		Status:        req.Status,
		AfterSaleType: req.AfterSaleType,
		StartTime:     req.StartTime,
		EndTime:       req.EndTime,
		OrderBy:       orderBys,
		FilterBy:      filterBys,
		WithAddress:   req.WithAddress,
		WithMedia:     req.WithMedia,
		WithPayment:   req.WithPayment,
	})
	if err != nil {
		return nil, err
	}

	resp := &types.BackendAfterSaleListResp{
		BaseDataInfo: types.BaseDataInfo{
			Success: true,
			Msg:     l.svcCtx.Trans.Trans(l.ctx, i18n.Success),
		},
		Data: types.AfterSaleListInfo{
			BaseListInfo: types.BaseListInfo{
				Current:  page,
				PageSize: pageSize,
				Total:    data.GetTotal(),
			},
			StatusStatisticMap: data.StatusStatisticMap,
		},
	}

	for _, v := range data.List {
		var mobile *string
		if v.Mobile != nil {
			mobile = pointy.GetPointer(userx.UserMsgEncipher(*v.Mobile, userx.MODEL))
		}

		var addresses []*types.OrderAddressInfo
		if len(v.Addresses) > 0 {
			for _, a := range v.Addresses {
				addresses = append(addresses, &types.OrderAddressInfo{
					Id:         a.Id,
					OrderId:    a.OrderId,
					UserId:     a.UserId,
					Consignee:  a.Consignee,
					Mobile:     a.Mobile,
					Province:   a.Province,
					City:       a.City,
					District:   a.District,
					Address:    a.Address,
					PostalCode: a.PostalCode,
					RegionCode: a.RegionCode,
					Label:      a.Label,
				})
			}
		}

		var payments []*types.OrderPaymentInfo
		if len(v.Payment) > 0 {
			for _, p := range v.Payment {
				payments = append(payments, &types.OrderPaymentInfo{
					Id:      p.Id,
					OrderId: p.OrderId,
					No:      p.No,
					Amount:  p.Amount,
					Type:    p.Type,
					Name:    p.Name,
					Code:    p.Code,
					PaidAt:  p.PaidAt,
				})
			}
		}

		var media []*types.MediaInfo
		if len(v.Media) > 0 {
			for _, m := range v.Media {
				var url string
				if m.Url != nil && len(*m.Url) > 0 {
					url = *m.Url
				}
				if len(url) == 0 && m.Uri != nil && len(*m.Uri) > 0 {
					url = *m.Uri
				}
				filename, mimeType, metaData := utils.ParseMetaData(m.MetaData)
				media = append(media, &types.MediaInfo{
					Uid:       m.Uid,
					Id:        m.Id,
					Thumbnail: m.Thumbnail,
					Order:     m.Order,
					Url:       pointy.GetPointer(url),
					Name:      pointy.GetPointer(filename),
					MimeType:  pointy.GetPointer(mimeType),
					AltText:   m.AltText,
					MetaData:  pointy.GetPointer(metaData),
				})
			}
		}

		option := utils.GetOptionByStatus(v.Status)
		resp.Data.List = append(resp.Data.List, &types.AfterSaleInfo{
			BaseIDInfo: types.BaseIDInfo{
				Id:         v.Id,
				CreatedAt:  v.CreatedAt,
				UpdatedAt:  v.UpdatedAt,
				DeletedAt:  v.DeletedAt,
				CanAccept:  option.CanAccept,
				CanReject:  option.CanReject,
				CanRemove:  option.CanRemove,
				CanRestore: option.CanRestore,
			},
			AfterSaleSn:      v.AfterSaleSn,
			OrderId:          v.OrderId,
			OrderItemId:      v.OrderItemId,
			OrderSn:          v.OrderSn,
			ProductId:        v.ProductId,
			ProductCode:      v.ProductCode,
			ProductTitle:     v.ProductTitle,
			ProductSkuId:     v.ProductSkuId,
			ProductSkuCode:   v.ProductSkuCode,
			ProductSku:       v.ProductSku,
			SkuThumbUrl:      v.SkuThumbUrl,
			ProductPrice:     v.ProductPrice,
			Quantity:         v.Quantity,
			UserId:           v.UserId,
			NickName:         v.NickName,
			Mobile:           mobile,
			ReturnAddressId:  v.ReturnAddressId,
			AfterSaleType:    v.AfterSaleType,
			RefundType:       v.RefundType,
			ReturnType:       v.ReturnType,
			RefundAmount:     v.RefundAmount,
			RefundDetails:    v.RefundDetails,
			Remark:           v.Remark,
			ExpressSn:        v.ExpressSn,
			ReasonForRefusal: v.ReasonForRefusal,
			Status:           v.Status,
			ProcessTime:      v.ProcessTime,
			Addresses:        addresses,
			Media:            media,
			Payments:         payments,
		})
	}

	return resp, nil
}
